Next | Prev | Up | Top | Contents | Index

Semaphore and Spinlock Calls

The remainder of this chapter is a listing of semaphore and spinlock calls. In each case, an example of the call precedes a brief explanation:


semap

#include <sys/types.h>
#include <sys/sema.h>
void initnsema(sema_t *semap, int value, char *name);
Allocate and initialize a semaphore addressed by semap, given value and name (for debugging).


freesema

void freesema(sema_t *semap);

Free the semaphore addressed by semap.


psema

int psema(sema_t *semap, int priority);

Decrement the current semaphore value by 1; if the semaphore value becomes less than 0, sleep at the given priority. The priority is the same as that given to sleep. The flag bit PCATCH may be bit-wise ORed into the priority if the sleep is breakable (greater than PZERO) and it is desired to catch the signal (as is usually the case).

The call may be prefixed with ap if the call is to be a NOP on single processors. This is often the case when the semaphore is used for locking.

This function returns 0 in normal operation or -1 if PCATCH is specified and a signal interrupted the sleep.


vsema

int vsema(sema_t *semap);

Increment the current semaphore value by 1; if the result is less than or equal to 0, place a process sleeping on the semaphore onto the run queue. As above, the call may be prefixed with ap if the call is to be a NOP on single processors.

This function returns 0 if no process is waiting on the semaphore, or 1 if a process is awakened.


cpsema

int cpsema(sema_t *semap);

This call conditionally provides the functionality of the psema operation. If the semaphore count is already less than 0, the function does not affect the semaphore value and simply returns 0. Otherwise, the semaphore count is decremented.

Note: In no case does the calling process sleep; this function can be useful to test whether a given lock has been acquired.


cvsema

int cvsema(sema_t *semap);

This function wakes up a process on the semaphore if there is one. More precisely, if the semaphore count is less than 0, it increments the semaphore count, places a process on the run queue, and returns 1; otherwise, the semaphore is unaffected and the function returns 0.


LOCK_ALLOC

lock_t *LOCK_ALLOC(uchar_t hierarchy, pl_t min_pl lkinfo_t *lkinfop, int flag);

This call dynamically allocates and initializes a basic lock. The lock is initialized to the unlocked state. Silicon Graphics does not support the compilation option _LOCKTEST, but does provide splockmeter for debugging purpose.


LOCK_DEALLOC

void LOCK_DEALLOC(lock_t *lockp);

This call frees an instance of a basic lock.


LOCK

int LOCK(lock_t, lock, int (*splr)());

On multiprocessor systems, this call acquires the given spinlock, lock. The interrupt priority level is set to at least splr while the lock is acquired.

On single processor systems, this calls the spl function splr.

This function returns the old priority level.


UNLOCK

void UNLOCK(lock_t lock, int s);

On multiprocessor systems, this call releases the given spinlock lock and restores the interrupt priority level to s.

On single-processor systems, restore the interrupt priority level to s. This is the value returned to LOCK above.


SLEEP_LOCK

void SLEEP_LOCK(sleep_t *lockp, int priority);

This call acquires the sleep lock specified by lockp. If the lock is not immediately available, the caller is put to sleep (the caller's execution is suspended and other processes may be scheduled) until the lock becomes available to the caller, at which point the caller wakes up and returns with the lock held.

The caller is not interrupted by signals while sleeping inside SLEEP_LOCK. See psema(D3X).


SLEEP_LOCK_SIG

boolean_t SLEEP_LOCK_SIG(sleep_t *lockp, int priority);

This function acquires the sleep lock specified by lockp. If the lock is not immediately available, the caller is put to sleep (the caller's execution is suspended and other processes may be scheduled) until the lock becomes available to the caller, at which point the caller wakes up and returns with the lock held.

SLEEP_LOCK_SIG may be interrupted by a signal, in which case it may return early without acquiring the lock.

If the function is interrupted by a job control stop signal (such as SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU), which results in the caller entering a stopped state, the SLEEP_LOCK_SIG function transparently retries the lock operation upon continuing (the call will not return without the lock).

If the function is interrupted by a signal other than a job control stop signal, or by a job control stop signal that does not result in the caller stopping (because the signal has a non-default disposition), the SLEEP_LOCK_SIG call returns early without acquiring the lock.


SLEEP_UNLOCK

void SLEEP_UNLOCK(sleep_t *lockp);

This function releases the sleep lock specified by lockp. If there are processes waiting for the lock, one of the waiting processes is awakened. See vsema(D3X).


SLEEP_TRYLOCK

boolean_t SLEEP_TRYLOCK(sleep_t *lockp);

This function tries to acquire a sleep lock. See cpsema(D3X).


TRYLOCK

int TRYLOCK(lock_t *lockp, pl_t pl);

This function tries to acquire a basic lock.

Caution: Drivers that reacquire multiple locks may deadlock when an asynchronous processor obtains a needed lock and does not free it because a lock held by another processor is also looking for a lock.


semap
freesema
psema
vsema
cpsema
cvsema
LOCK_ALLOC
LOCK_DEALLOC
LOCK
UNLOCK
SLEEP_LOCK
SLEEP_LOCK_SIG
SLEEP_UNLOCK
SLEEP_TRYLOCK
TRYLOCK

Next | Prev | Up | Top | Contents | Index